package com.sc.admin.core.api.web;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.sc.admin.core.bo.ResourceBo;
import com.sc.admin.core.service.*;
import com.sc.admin.core.service.*;
import com.sc.common.annotations.OperationLog;
import com.sc.common.annotations.WebApi;
import com.sc.common.context.DefaultBusinessContext;
import com.sc.common.dto.WebResponseDto;
import com.sc.common.entity.admin.company.SysCompany;
import com.sc.common.entity.admin.company.SysCompanyList;
import com.sc.common.entity.admin.department.SysDepartment;
import com.sc.common.entity.admin.department.SysDepartmentList;
import com.sc.common.entity.admin.organization.SysOrganization;
import com.sc.common.entity.admin.organization.SysOrganizationSearch;
import com.sc.common.entity.admin.project.SysProject;
import com.sc.common.entity.admin.project.SysProjectList;
import com.sc.common.entity.admin.role.SysRole;
import com.sc.common.entity.admin.role.SysRoleList;
import com.sc.common.entity.admin.user.SysUser;
import com.sc.common.entity.admin.user.SysUserList;
import com.sc.common.enums.DataDictionaryEnum;
import com.sc.common.enums.OperationLogEnum;
import com.sc.common.util.MyStringUtils;
import com.sc.common.util.cache.DataDictionaryUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;
import java.util.*;

/**
 * Created by wust on 2019/6/3.
 */
@WebApi
@RequestMapping("/web/v1/OrganizationController")
@RestController
public class OrganizationController {
    @Autowired
    private SysOrganizationService sysOrganizationServiceImpl;

    @Autowired
    private SysCompanyService sysCompanyServiceImpl;

    @Autowired
    private SysDepartmentService sysDepartmentServiceImpl;

    @Autowired
    private SysRoleService sysRoleServiceImpl;

    @Autowired
    private SysUserService sysUserServiceImpl;

    @Autowired
    private SysProjectService sysProjectServiceImpl;

    @Autowired
    private SysUserOrganizationService sysUserOrganizationServiceImpl;

    @Autowired
    private SysResourceService sysResourceService;

    @Autowired
    private CommonService commonServiceImpl;

    @Autowired
    private ResourceBo resourceBo;

    static Logger logger = LogManager.getLogger(OrganizationController.class);


    @RequestMapping(value = "/buildTree",method = RequestMethod.POST)
    public WebResponseDto buildTree(@RequestBody SysOrganizationSearch search){
        WebResponseDto responseDto = this.sysOrganizationServiceImpl.buildLeftTree(search);
        return responseDto;
    }


    @RequestMapping(value = "/checkUser",method = RequestMethod.POST)
    public WebResponseDto checkUser(@RequestParam String loginName, @RequestParam Long organizationId){
        WebResponseDto responseDto = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();

        SysUser userSearch = new SysUser();
        userSearch.setLoginName(loginName);
        SysUser user = sysUserServiceImpl.selectOne(userSearch);
        if(user == null){
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("该员工还没有入职，无法添加到组织");
            return responseDto;
        }


        SysOrganization organization4role = sysOrganizationServiceImpl.selectByPrimaryKey(organizationId);
        SysOrganization organization4department = sysOrganizationServiceImpl.selectByPrimaryKey(organization4role.getPid());
        SysOrganization organization4unknow = sysOrganizationServiceImpl.selectByPrimaryKey(organization4department.getPid());
        Long departmentId = organization4department.getRelationId();
        Long roleId = organization4role.getRelationId();

        SysOrganization organizationSearch = new SysOrganization();
        organizationSearch.setPid(organizationId);
        organizationSearch.setRelationId(user.getId());
        SysOrganization organization = sysOrganizationServiceImpl.selectOne(organizationSearch);
        if(organization != null){
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("当前选择的岗位下面已经存在该员工，不需要重复添加。");
            return responseDto;
        }

        if(DataDictionaryEnum.USER_TYPE_AGENT.getStringValue().equals(user.getType())){
            if(!DataDictionaryEnum.ORGANIZATION_TYPE_AGENT.getStringValue().equals(organization4unknow.getType())){
                logger.error("当前登录账号[{}]试图将代理商账号[{}]添加到非代理商组织，已被阻止",ctx.getAccountCode(),user.getLoginName());
                responseDto.setFlag(WebResponseDto.INFO_WARNING);
                responseDto.setMessage("非法的操作，系统拒绝：帐号类型不符");
                return responseDto;
            }
        }else if(DataDictionaryEnum.USER_TYPE_PARENT_COMPANY.getStringValue().equals(user.getType())){
            if(!DataDictionaryEnum.ORGANIZATION_TYPE_PARENT_COMPANY.getStringValue().equals(organization4unknow.getType())){
                logger.error("当前登录账号[{}]试图将总公司账号[{}]添加到非总公司组织，已被阻止",ctx.getAccountCode(),user.getLoginName());
                responseDto.setFlag(WebResponseDto.INFO_WARNING);
                responseDto.setMessage("非法的操作，系统拒绝：帐号类型不符");
                return responseDto;
            }
        }else if(DataDictionaryEnum.USER_TYPE_BRANCH_COMPANY.getStringValue().equals(user.getType())){
            if(!DataDictionaryEnum.ORGANIZATION_TYPE_BRANCH_COMPANY.getStringValue().equals(organization4unknow.getType())){
                logger.error("当前登录账号[{}]试图将分公司账号[{}]添加到非分公司组织，已被阻止",ctx.getAccountCode(),user.getLoginName());
                responseDto.setFlag(WebResponseDto.INFO_WARNING);
                responseDto.setMessage("非法的操作，系统拒绝：帐号类型不符");
                return responseDto;
            }
        }else if(DataDictionaryEnum.USER_TYPE_PROJECT.getStringValue().equals(user.getType())){
            SysDepartment department = sysDepartmentServiceImpl.selectByPrimaryKey(departmentId);
            if(!"A102701".equals(department.getType())){
                logger.error("当前登录账号[{}]试图将项目账号[{}]添加到到非项目部门，已被阻止。",ctx.getAccountCode(),user.getLoginName());
                responseDto.setFlag(WebResponseDto.INFO_WARNING);
                responseDto.setMessage("非法的操作，系统拒绝：帐号类型不符");
                return responseDto;
            }
        }else if(DataDictionaryEnum.USER_TYPE_BUSINESS.getStringValue().equals(user.getType())){
            SysDepartment department = sysDepartmentServiceImpl.selectByPrimaryKey(departmentId);
            if(!"A102702".equals(department.getType())){
                logger.error("当前登录账号[{}]试图将业务账号[{}]添加到到非业务部门，已被阻止",ctx.getAccountCode(),user.getLoginName());
                responseDto.setFlag(WebResponseDto.INFO_WARNING);
                responseDto.setMessage("非法的操作，系统拒绝：帐号类型不符");
                return responseDto;
            }
        }


        SysRole role = sysRoleServiceImpl.selectByPrimaryKey(roleId);
        if(user.getAgentId() != null && user.getAgentId() != 0 && user.getAgentId().intValue() != role.getAgentId().intValue()){
            logger.error("当前登录账号[{}]试图把员工[{}]绑定到不属于同一个代理商的岗位，已被阻止",ctx.getAccountCode(),user.getLoginName());
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("非法的操作，系统拒绝");
            return responseDto;
        }


        List<SysUserList> userLists = new ArrayList<>(1);
        SysUserList userList = new SysUserList();
        BeanUtil.copyProperties(user,userList);
        userList.setTypeLabel(DataDictionaryUtil.getLookupNameByCode(ctx.getLocale().toString(),user.getType()));
        userList.setStatusLabel(DataDictionaryUtil.getLookupNameByCode(ctx.getLocale().toString(),user.getStatus()));
        userList.setSexLabel(DataDictionaryUtil.getLookupNameByCode(ctx.getLocale().toString(),user.getSex()));
        userLists.add(userList);
        responseDto.setLstDto(userLists);
        return responseDto;
    }


    @RequestMapping(value = "/findRelationBeanByRelationId",method = RequestMethod.POST)
    public WebResponseDto findRelationBeanByRelationId(@RequestParam String type, @RequestParam Long relationId){
        WebResponseDto responseDto = new WebResponseDto();
        if(DataDictionaryEnum.ORGANIZATION_TYPE_DEPARTMENT.getStringValue().equals(type)){
            SysDepartment department = sysDepartmentServiceImpl.selectByPrimaryKey(relationId);
            responseDto.setObj(department);
        }else {
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("系统没有此组织类型");
        }
        return responseDto;
    }

    /**
     * 得到默认运营管理员账号
     * @param userType
     * @param accountPrefix
     * @return
     */
    @RequestMapping(value = "/getDefaultAdminAccount",method = RequestMethod.POST)
    public WebResponseDto getDefaultAdminAccount(@RequestParam String userType, @RequestParam String accountPrefix){
        WebResponseDto responseDto = new WebResponseDto();

        Example example = new Example(SysUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("type",userType);
        criteria.andLike("loginName",accountPrefix + "%");
        example.setOrderByClause("login_name DESC");
        List<SysUser> userList = sysUserServiceImpl.selectByExample(example);
        if(CollectionUtil.isNotEmpty(userList)){
            SysUser user = userList.get(0);
            int accountInt = Integer.valueOf(user.getLoginName().replace(accountPrefix,"")) + 1;
            String accountStr = accountPrefix + accountInt;
            responseDto.setObj(accountStr);
        }
        return responseDto;
    }

    @OperationLog(moduleName= OperationLogEnum.MODULE_ADMIN_ORGANIZATION,businessName="创建公司",operationType= OperationLogEnum.Insert)
    @RequestMapping(value = "/createCompany",method = RequestMethod.POST)
    public WebResponseDto createCompany(@RequestBody Map map){
        WebResponseDto responseDto = sysOrganizationServiceImpl.createCompany(map);
        return responseDto;
    }


    @OperationLog(moduleName= OperationLogEnum.MODULE_ADMIN_ORGANIZATION,businessName="创建项目",operationType= OperationLogEnum.Insert)
    @RequestMapping(value = "/createProject",method = RequestMethod.POST)
    public WebResponseDto createProject(@RequestBody Map map){
        WebResponseDto responseDto = sysOrganizationServiceImpl.createProject(map);
        return responseDto;
    }

    @OperationLog(moduleName= OperationLogEnum.MODULE_ADMIN_ORGANIZATION,businessName="创建部门",operationType= OperationLogEnum.Insert)
    @RequestMapping(value = "/createDepartment",method = RequestMethod.POST)
    public WebResponseDto createDepartment(@RequestBody Map map){
        WebResponseDto responseDto = sysOrganizationServiceImpl.createDepartment(map);
        return responseDto;
    }

    @OperationLog(moduleName= OperationLogEnum.MODULE_ADMIN_ORGANIZATION,businessName="创建岗位",operationType= OperationLogEnum.Insert)
    @RequestMapping(value = "/createRole",method = RequestMethod.POST)
    public WebResponseDto createRole(@RequestBody Map map){
        WebResponseDto responseDto = sysOrganizationServiceImpl.createRole(map);
        return responseDto;
    }


    @OperationLog(moduleName= OperationLogEnum.MODULE_ADMIN_ORGANIZATION,businessName="添加员工",operationType= OperationLogEnum.Insert)
    @RequestMapping(value = "/addUser",method = RequestMethod.POST)
    public WebResponseDto addUser(@RequestBody Map map){
        WebResponseDto responseDto = sysOrganizationServiceImpl.addUser(map);
        return responseDto;
    }

    @OperationLog(moduleName= OperationLogEnum.MODULE_ADMIN_ORGANIZATION,businessName="删除",operationType= OperationLogEnum.Delete)
    @RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
    public WebResponseDto delete(@PathVariable Long id){
        WebResponseDto responseDto = new WebResponseDto();
        SysOrganization organization = sysOrganizationServiceImpl.selectByPrimaryKey(id);
        if(organization != null){
            SysOrganizationSearch sysOrganizationSearch = new SysOrganizationSearch();
            sysOrganizationSearch.setPid(id);
            List<SysOrganization> sysOrganizationLists = sysOrganizationServiceImpl.select(sysOrganizationSearch);
            if(org.apache.commons.collections.CollectionUtils.isNotEmpty(sysOrganizationLists)){
                responseDto.setFlag(WebResponseDto.INFO_WARNING);
                responseDto.setMessage("您要删除的记录存在子节点，无法删除带有子节点的数据，请先删除所有子节点");
                return responseDto;
            }
            if(DataDictionaryEnum.ORGANIZATION_TYPE_PROJECT.getStringValue().equals(organization.getType())) { // 删除项目节点并删除数据库
                commonServiceImpl.cleaningProjectAllData(organization.getRelationId());
            }else{
                sysOrganizationServiceImpl.delete(id);
            }
        }
        return responseDto;
    }


    /**
     * 获取当前选定角色的功能权限树
     * @param organizationId 选中角色对应的组织id
     * @param grandfatherType 选中角色的爷爷是什么组织类型
     * @return
     */
    @RequestMapping(value = "/buildFunctionTreeByRoleId",method = RequestMethod.POST)
    public WebResponseDto buildFunctionTreeByRoleId(@RequestParam("organizationId") Long organizationId, @RequestParam("grandfatherType") String grandfatherType){
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();

        WebResponseDto responseDto = new WebResponseDto();
        if (organizationId == null) {
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("请选择角色");
            return responseDto;
        }

        if (MyStringUtils.isBlank(MyStringUtils.null2String(grandfatherType))) {
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("组织架构格式存在错误，无法找到当前选中角色的爷爷在组织架构中的类型");
            return responseDto;
        }

        SysOrganization organization4role = sysOrganizationServiceImpl.selectByPrimaryKey(organizationId);
        SysOrganization organization4department = sysOrganizationServiceImpl.selectByPrimaryKey(organization4role.getPid());
        SysDepartment department = sysDepartmentServiceImpl.selectByPrimaryKey(organization4department.getRelationId());

        String jsonString = "";

        if(ctx.isSuperAdmin() || ctx.isAdmin()){ // 当前登录账号类型是系统管理员账号类型
            if ("A101109".equals(grandfatherType)) { // 选中角色的爷爷组织类型：项目
                if ("A102701".equals(department.getType())) { // 选中角色所属部门类型是“运营管理部”
                    // 找项目菜单
                    jsonString = resourceBo.buildFunctionTreeByOrganizationId("A100410", organizationId);
                } else {
                    // 找业务菜单
                    jsonString = resourceBo.buildFunctionTreeByOrganizationId("A100411", organizationId);
                }
            } else if ("A101107".equals(grandfatherType)) { // 选中角色的爷爷组织类型：分公司
                // 找分公司菜单
                jsonString = resourceBo.buildFunctionTreeByOrganizationId("A100409", organizationId);
            } else if ("A101104".equals(grandfatherType)) { // 选中角色的爷爷组织类型：总公司
                // 找分总司菜单
                jsonString = resourceBo.buildFunctionTreeByOrganizationId("A100406", organizationId);
            } else if ("A101101".equals(grandfatherType)) { // 选中角色的爷爷组织类型：代理商
                // 找代理商菜单
                jsonString = resourceBo.buildFunctionTreeByOrganizationId("A100403", organizationId);
            }
        }else if(ctx.isStaff()){ // 当前登录账号类型是员工账号类型
            String userType = ctx.getUser().getType();
            if ("A100403".equals(userType)) { // 当前登录账号类型：代理商
                if ("A101109".equals(grandfatherType)) { // 选中角色的爷爷组织类型：项目
                    // 找业务菜单
                    jsonString = resourceBo.buildFunctionTreeByOrganizationId("A100411", organizationId);
                } else if ("A101107".equals(grandfatherType)) { // 选中角色的爷爷组织类型：分公司
                    // 找分公司菜单
                    jsonString = resourceBo.buildFunctionTreeByOrganizationId("A100409", organizationId);
                } else if ("A101104".equals(grandfatherType)) { // 选中角色的爷爷组织类型：总公司
                    // 找分总司菜单
                    jsonString = resourceBo.buildFunctionTreeByOrganizationId("A100406", organizationId);
                } else if ("A101101".equals(grandfatherType)) { // 选中角色的爷爷组织类型：代理商
                    responseDto.setFlag(WebResponseDto.INFO_WARNING);
                    responseDto.setMessage("您所属岗位权限不足，不足以给同级别到岗位设置权限");
                    return responseDto;
                }
            } else if ("A100406".equals(userType)) { // 当前登录账号类型：总公司
                if ("A101109".equals(grandfatherType)) { // 选中角色的爷爷组织类型：项目
                    // 找业务菜单
                    jsonString = resourceBo.buildFunctionTreeByOrganizationId("A100411", organizationId);
                } else if ("A101107".equals(grandfatherType)) { // 选中角色的爷爷组织类型：分公司
                    // 找分公司菜单
                    jsonString = resourceBo.buildFunctionTreeByOrganizationId("A100409", organizationId);
                } else if ("A101104".equals(grandfatherType)) { // 选中角色的爷爷组织类型：总公司
                    responseDto.setFlag(WebResponseDto.INFO_WARNING);
                    responseDto.setMessage("您所属岗位权限不足，不足以给同级别到岗位设置权限");
                    return responseDto;
                }
            } else if ("A100409".equals(userType)) { // 当前登录账号类型：分公司
                if ("A101109".equals(grandfatherType)) { // 选中角色的爷爷组织类型：项目
                    if ("A102701".equals(department.getType())) { // 选中角色所属部门类型是“运营管理部”
                        // 项目管理员菜单
                        jsonString = resourceBo.buildFunctionTreeByOrganizationId("A100410", organizationId);
                    } else {
                        // 找业务菜单
                        jsonString = resourceBo.buildFunctionTreeByOrganizationId("A100411", organizationId);
                    }
                } else if ("A101107".equals(grandfatherType)) { // 选中角色的爷爷组织类型：分公司
                    responseDto.setFlag(WebResponseDto.INFO_WARNING);
                    responseDto.setMessage("您所属岗位权限不足，不足以给同级别到岗位设置权限");
                    return responseDto;
                }
            } else if ("A100410".equals(userType)) { // 当前登录账号类型：项目
                if ("A101109".equals(grandfatherType)) { // 选中角色的爷爷组织类型：项目
                    // 找业务菜单
                    jsonString = resourceBo.buildFunctionTreeByOrganizationId("A100411", organizationId);
                }
            } else if ("A100411".equals(userType)) { // 当前登录账号类型：业务员
                responseDto.setFlag(WebResponseDto.INFO_WARNING);
                responseDto.setMessage("您没有权限设置资源权限");
                return responseDto;
            }
        }

        responseDto.setObj(jsonString);
        return responseDto;
    }



    /**
     * 设置功能权限
     * @param jsonObject
     * @return
     */
    @RequestMapping(value = "/setFunctionPermissions",method = RequestMethod.POST)
    public WebResponseDto setFunctionPermissions(@RequestBody JSONObject jsonObject){
        WebResponseDto responseDto = sysOrganizationServiceImpl.setFunctionPermissions(jsonObject);
        return responseDto;
    }




    /**
     * 根据组织id获取明细
     * @param id
     * @return
     */
    @RequestMapping(value = "/getDetailById",method = RequestMethod.POST)
    public WebResponseDto getDetailByType(@RequestParam Long id){
        WebResponseDto responseDto = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();

        SysOrganization organization = sysOrganizationServiceImpl.selectByPrimaryKey(id);
        if(organization != null){
            String type = organization.getType();
            Long relationId = organization.getRelationId();
            if("A101101".equals(type) || "A101104".equals(type) || "A101107".equals(type)){
                SysCompany company = sysCompanyServiceImpl.selectByPrimaryKey(relationId);
                SysCompanyList companyList = new SysCompanyList();
                BeanUtil.copyProperties(company,companyList);
                companyList.setTypeLabel(DataDictionaryUtil.getLookupNameByCode(ctx.getLocale().toString(),company.getType()));
                responseDto.setObj(companyList);
            }else if("A101109".equals(type)){
                SysProject project = sysProjectServiceImpl.selectByPrimaryKey(relationId);
                SysProjectList projectList = new SysProjectList();
                BeanUtil.copyProperties(project,projectList);
                responseDto.setObj(projectList);
            }else if("A101111".equals(type)){
                SysDepartment department = sysDepartmentServiceImpl.selectByPrimaryKey(relationId);
                SysDepartmentList departmentList = new SysDepartmentList();
                BeanUtil.copyProperties(department,departmentList);
                departmentList.setTypeLabel(DataDictionaryUtil.getLookupNameByCode(ctx.getLocale().toString(),department.getType()));
                responseDto.setObj(departmentList);
            }else if("A101113".equals(type)){
                SysRole role = sysRoleServiceImpl.selectByPrimaryKey(relationId);
                SysRoleList roleList = new SysRoleList();
                BeanUtil.copyProperties(role,roleList);
                roleList.setStatusLabel(DataDictionaryUtil.getLookupNameByCode(ctx.getLocale().toString(),role.getStatus()));
                responseDto.setObj(roleList);
            }else if("A101115".equals(type)){
                SysUser user = sysUserServiceImpl.selectByPrimaryKey(relationId);
                SysUserList userList = new SysUserList();
                BeanUtil.copyProperties(user,userList);
                userList.setStatusLabel(DataDictionaryUtil.getLookupNameByCode(ctx.getLocale().toString(),user.getStatus()));
                userList.setTypeLabel(DataDictionaryUtil.getLookupNameByCode(ctx.getLocale().toString(),user.getType()));
                userList.setSexLabel(DataDictionaryUtil.getLookupNameByCode(ctx.getLocale().toString(),user.getSex()));
                responseDto.setObj(userList);
            }
        }
        return responseDto;
    }
}
